iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 28
1
Blockchain

區塊鏈淺談:從創世到末日,上月球到落地系列 第 28

當機率只是天文數字的尾數,lucky wallet

  • 分享至 

  • xImage
  •  

在學習資訊的過程中,曾今懷疑雜湊值的碰撞機率,一句機率很低,並無法說服我。接觸密碼學與機統後,才明白那個『很低』到底有多低。

也有遇到別人問過,『區塊鏈用公開金鑰加密演算法的私鑰採生地址,那如果有兩個人同時生成一樣的私鑰,或者不同公鑰透過雜湊後的到相同的值,不就能夠操作別的人錢包嗎?』,對於問題的答案是肯定的,但是這個機率,比天上星星數量的倒數遠遠還要小。

說一個密碼學機率的基礎問題,『你覺得一個30人的班級,有兩個人同一天生日的機率有多少?』,答案是70%。365天這麼多天,機率有這麼大嗎?數學論證就是如此,附上維基百科 Birthday problem,與使用這個原理產生的密碼學攻擊 Birthday attack

透過生日問題,理解了碰中機率與數量的關係後,那試算一下橢圓曲線密碼學 SECP256k1 所能產生的私鑰個數約有 2^256 ~= 1.2 × 10^77 ,然後再比較一下剛剛維基百科中的表格,要大於 50% 碰撞率至少要有 4.0 × 10^38 個。這到量到底有多大?台灣約有 2,300 萬人,日本約有1億2千人,全世界在2017年4月統計約有75億,銀河系恆星數目約有1000-4000億 (2.5×10^11)。(以上數字都只是估算,僅供參考)

這樣你感受到其中的量級差距與碰撞機率了嗎?雜湊函示 sha256 也是相同的。

先不論到底有多『理論上有可能,實際上機率趨近於零』的問題。假設今天你相信你就是這麼歐洲人,玩遊戲課金抽寶沒有抽不到的,那就讓來寫一個 lucky wallet 吧!

使用 python 實作,隨機建立一個ECC公、私鑰並生成 ETH 錢包地址,查詢是否有錢,有的話就轉到目標地址。理論上,這個程式永遠不會執行成功啦!如果真的執行成功,記得分我一點啊!

# https://github.com/SecondDim/PracticePython/blob/master/Ethereum/lucky_wallet.py
# 如果喜歡這支程式,歡迎施捨一點 Ether~
# ETH:0xe44bd95c1ddb1e2d6ebdd08d39b18264f530d5cb
# =============================================
#! /usr/bin/python3

# pip install ecdsa
# pip install pysha3

# Ether 使用 ecc 簽章
from ecdsa import SigningKey, SECP256k1
import sha3

# 與 RPC 連線
from web3 import Web3, HTTPProvider

# 編碼
import rlp

from ethereum.transactions import Transaction

import time
import binascii

lucky_wallet = ""
rpc_server = ""


def main():
    
    # 生成私鑰、公鑰
    priv = SigningKey.generate(curve=SECP256k1)
    pub = priv.get_verifying_key().to_string()
    
    # 生成錢包地址
    keccak = sha3.keccak_256()
    keccak.update(pub)
    guess_address = "0x" + keccak.hexdigest()[24:]

    # 建立 RPC 連線,並取得帳戶餘額
    w3 = Web3(HTTPProvider(rpc_server))
    guess_address_balance = w3.eth.getBalance(guess_address)
    
    # 理論上永遠不會是 True
    if guess_address_balance != 0:

        # 計算手續費並將餘額轉入指定地址
        gas_price = w3.eth.gasPrice
        tx_val = guess_address_balance - (gas_price * 21000)

        if tx_val <= 0:
            tx_val = guess_address_balance - (1 * 21000)

        tx = Transaction(
            nonce=w3.eth.getTransactionCount(guess_address),
            gasprice=gas_price,
            startgas=21000,
            to=lucky_wallet,
            value=tx_val,
            data=b'',
        )

        tx.sign(priv.to_string())
        raw_tx = rlp.encode(tx)
        raw_tx_hex = w3.toHex(raw_tx)
        tx_hash = w3.eth.sendRawTransaction(raw_tx_hex)
        print("Tx: " + tx_hash)


if __name__ == '__main__':

    if lucky_wallet == "" or rpc_server == "":
        print("You should setup arg lucky_wallet and rpc_server first!")

    else:
        print("starting......")
        
        while True:
            try:
                main()
            except KeyboardInterrupt:
                break
            except Exception as e:
                print(e)
            finally:
                pass

            time.sleep(0.01)


上一篇
建立以太坊節點,geth
下一篇
你看網頁我賺錢,coinhive
系列文
區塊鏈淺談:從創世到末日,上月球到落地30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言